<script setup lang="ts">
import { ref, reactive, nextTick, onMounted, onUnmounted } from "vue";
import votesImg from '@/assets/img/content-img/votes-img.png';
import throughputImg from '@/assets/img/content-img/throughput-img.png';
import piecesIimg from '@/assets/img/content-img/pieces-img.png';
import * as echarts from 'echarts';
import chinaGeoJson from './china-geo-json.json'
import { post } from '@/utils/request'
import { mapApi, statistics } from '@/api'
import { ponitImg, cityPointImg } from '@/assets/base64'
let titleData: any = reactive([])
const myChart: any = ref(null);
const seriesPoingState: any = ref(false) //控制point样式
const fbzxPointList: any = ref([]); // 分拨中心点位数据
const pointList: any = ref([]) // 点数据
const lineList: any = ref([]) // 线数据
const drillDownHistory: any = ref([]) // 下钻历史记录
let clickTimeout: any = null; // 点击超时定时器
// 初始化区域映射颜色
const areaColor: any = {
  610000: 'rgba(41, 241, 250, 0.5)',    // 陕西---50%
  140000: 'rgba(49, 204, 147, 0.5)',    // 山西---50%
  150000: 'rgba(97, 145, 236, 0.3)',    // 内蒙---30%
  640000: 'rgba(71, 31, 173, 0.3)',     // 宁夏---30%
  620000: 'rgba(255, 208, 59, 0.3)',    // 甘肃---30%
  510000: 'rgba(97, 145, 236, 0.5)',    // 四川---50%
  530000: 'rgba(233, 141, 26, 0.5)',    // 云南---50%
  520000: 'rgba(245, 108, 108, 0.5)',   // 贵州---50%
  500000: 'rgba(41, 241, 250, 0.2)',    // 重庆---20%
  540000: 'rgba(245, 108, 108, 0.2)',   // 西藏---20%
  630000: 'rgba(41, 241, 250, 0.3)'     // 青海---30%
};
// 自定义 line 数据
const lineData = [
  {
    "val": 10,   // 值
    "blat": 30.659462, // 起始点纬度 (Begin Latitude)
    "blon": 104.065735, // 起始点经度 (Begin Longitude)
    "elat": 39.904989,   // 终点纬度 (End Latitude)
    "elon": 116.405285, // 终点经度 (End Longitude)
    "bcitysim": "四川省", // 起始城市名称 (Begin City Name)
    "ecitysim": "北京市" // 终点城市名称 (End City Name)
  },
  {
    "val": 10,
    "blat": 25.040609,
    "blon": 102.712251,
    "elat": 34.263161,
    "elon": 108.948024,
    "bcitysim": "云南省",
    "ecitysim": "陕西省"
  },
  {
    "val": 10,
    "blat": 25.040609,
    "blon": 102.712251,
    "elat": 30.659462,
    "elon": 104.065735,
    "bcitysim": "云南省",
    "ecitysim": "四川省"
  },
  {
    "val": 10,
    "blat": 34.27,
    "blon": 108.93,
    "elat": 36.07,
    "elon": 120.38,
    "bcitysim": "西安市",
    "ecitysim": "青岛市"
  },
  {
    "val": 10,
    "blat": 29.57,
    "blon": 106.55,
    "elat": 30.6,
    "elon": 114.3,
    "bcitysim": "重庆市",
    "ecitysim": "武汉市"
  },
  {
    "val": 9,
    "blat": 24.48,
    "blon": 118.08,
    "elat": 39.9,
    "elon": 116.4,
    "bcitysim": "厦门市",
    "ecitysim": "北京市"
  }, {
    "val": 2,
    "blat": 28.23,
    "blon": 112.93,
    "elat": 30.67,
    "elon": 104.07,
    "bcitysim": "长沙市",
    "ecitysim": "成都市"
  },
  {
    "val": 2,
    "blat": 31.57,
    "blon": 120.3,
    "elat": 39.12,
    "elon": 117.2,
    "bcitysim": "无锡市",
    "ecitysim": "天津市"
  },
  {
    "val": 2,
    "blat": 41.8,
    "blon": 123.43,
    "elat": 38.05,
    "elon": 114.52,
    "bcitysim": "沈阳市",
    "ecitysim": "石家庄市"
  },
  {
    "val": 2,
    "blat": 30.6,
    "blon": 114.3,
    "elat": 36.67,
    "elon": 116.98,
    "bcitysim": "武汉市",
    "ecitysim": "济南市"
  },
  {
    "val": 2,
    "blat": 28.23,
    "blon": 112.93,
    "elat": 30.28,
    "elon": 120.15,
    "bcitysim": "长沙市",
    "ecitysim": "杭州市"
  },
  {
    "val": 2,
    "blat": 24.48,
    "blon": 118.08,
    "elat": 30.28,
    "elon": 120.15,
    "bcitysim": "厦门市",
    "ecitysim": "杭州市"
  },
  {
    "val": 2,
    "blat": 30.67,
    "blon": 104.07,
    "elat": 25.05,
    "elon": 102.72,
    "bcitysim": "成都市",
    "ecitysim": "昆明市"
  },
  {
    "val": 2,
    "blat": 31.57,
    "blon": 120.3,
    "elat": 37.45,
    "elon": 121.43,
    "bcitysim": "无锡市",
    "ecitysim": "烟台市"
  },
  {
    "val": 2,
    "blat": 30.6,
    "blon": 114.3,
    "elat": 30.28,
    "elon": 120.15,
    "bcitysim": "武汉市",
    "ecitysim": "杭州市"
  },
];
var colors =
  ["#1DE9B6", "#EEDD78", "#32C5E9", "#FFDB5C", "#37A2DA", "#04B9FF"];
const getLineList = () => {
  lineList.value = []
  for (var i = 0; i < lineData.length; i++) {
    lineList.value.push({
      fromName: lineData[i].bcitysim,
      toName: lineData[i].ecitysim,
      coords: [
        [lineData[i].blon, lineData[i].blat],
        [lineData[i].elon, lineData[i].elat]
      ],
      count: lineData[i].val
    });
  }
}

function initEcharts(name: any, data: any) {
  const series = []
  // 下钻旗帜icon
  const iconPoint: any =// point样式
  {
    // name: 'pm2.5',
    type: 'scatter',
    coordinateSystem: 'geo',
    data: pointList.value,
    // symbolSize: 12,
    // // symbolSize: 20, // 图片大小
    // symbolOffset: [0, 0], // 调整位置（向上偏移10px）
    // symbolKeepAspect: true, // 保持图片宽高比
    // ssymbolSize: function (val: any) {
    //  return Math.min(val[2] / 10, 8); // 最大不超过8像素
    // },
    label: {
      show: false,
      formatter: '{b}',
      position: 'right',
      emphasis: {
        show: true
      }
    },
    itemStyle: {
      color: '#FF0000' //point颜色
    }
  }

  const defaultPoint: any = {
    // name: 'pm2.5',
    type: 'scatter',
    coordinateSystem: 'geo',
    data: pointList.value,
    symbolSize: 4,
    // ssymbolSize: function (val: any) {
    //  return Math.min(val[2] / 10, 8); // 最大不超过8像素
    // },
    label: {
      show: false,
      formatter: '{b}',
      position: 'right',
      emphasis: {
        show: true
      }
    },
    itemStyle: {
      color: '#FF0000' //point颜色
    }

  }
  // 默认样式
  let defaultSeries = [// line 样式
    {
      type: 'lines',
      zlevel: 2,
      effect: {
        show: true,
        period: 10, //箭头指向速度，值越小速度越快
        trailLength: 0.2, //特效尾迹长度[0,1]值越大，尾迹越长重
        symbol: 'arrow', //箭头图标
        symbolSize: 6, //图标大小
      },
      lineStyle: {
        normal: {
          color: colors[5],
          width: 1, //尾迹线条宽度
          opacity: 0.2, //尾迹线条透明度
          curveness: .3 //尾迹线条曲直度
        }
      },
      data: lineList.value
    },
    {
      type: "map",
      map: name, // 地图名称
      geoIndex: 0,
      roam: true,
      data: data, // 地图数据
      animation: true,
      animationDurationUpdate: 1000,
      animationEasingUpdate: 'cubicOut',
      // 系列特定的标签样式（会覆盖geo中的配置）
      // label: {
      //   show: true,
      //   color: '#fff',
      //   fontSize: 12,
      //   emphasis: { // 系列特定的悬停样式
      //     color: '#FFA500', // 橙色
      //     fontWeight: 'bold'
      //   }
      // }
    },]
  if (seriesPoingState.value) {
    series.push(...defaultSeries, iconPoint)
  } else {
    series.push(...defaultSeries, defaultPoint)
  }

  const option = {
    geo: {
      // 鼠标经过区域 文字样式
      label: {
        emphasis: {
          color: '#FFFFFF'
        }
      },
      // 使用 registerMap 注册的地图名称。
      map: name,
      roam: true,
      aspectScale: 0.75, // 调整南北拉伸比例
      layoutCenter: ['50%', '53%'], // 让地图居中
      layoutSize: '100%', // 调整地图大小（可用 100% 或具体像素值）
      // label: {      // 控制文字标签样式
      //   show: true, // 是否显示标签
      //   color: '#fff', // 文字颜色
      //   fontSize: 12,  // 字体大小
      //   // fontFamily: 'Microsoft YaHei', // 字体
      //   fontWeight: '200', // 字重（normal/bold）
      //   // align: 'center',     // 水平对齐（left/center/right）
      //   // verticalAlign: 'middle' // 垂直对齐（top/middle/bottom）
      // },
      itemStyle: { //地图区域样式
        borderWidth: 1.5, // 普通状态下的边框线粗细（默认是1）
        borderColor: 'rgba(31, 159, 171)', // 地图轮廓颜色
        areaColor: 'transparent', // 地图区域透明
        borderType: 'solid',     // 可选：'solid'（实线）、'dashed'（虚线）、'dotted'（点线）
      },
      animation: true,
      animationDurationUpdate: 1000, // 动画时长（ms）
      animationEasingUpdate: 'cubicOut', // 动画缓动
      regions: regionsList.value
    },
    itemStyle: {
      areaColor: '#f5f5f5',
      borderColor: '#999'
    },
    emphasis: { //鼠标悬停样式
      itemStyle: {
        areaColor: 'rgba(39, 59, 99)',
      },
      label: {
        // show: true,
        // fontSize: 12,
        // fontWeight: 'bold'
        show: true,
        fontSize: 12,
        fontWeight: 'bold',
        color: '#fff', // 明确设置悬停文本颜色为白色
        // 可以添加其他效果
        textBorderColor: '#000',
        textBorderWidth: 1,
        textShadowBlur: 4
      }
    },

    select: { // 选中区域样式
      itemStyle: {
        color: '#fff',
        areaColor: 'rgba(39, 59, 99)',
      },

    },
    series: series,
  };
  myChart.value.setOption(option, true);
  // 防抖锁

}

const regionsList: any = ref([])
// 本地GeoJSON地图数据 
const initMap = async () => {
  regionsList.value = []
  const adcode = "100000"; // 中国的行政区划代码
  myChart.value = echarts.init(document.getElementById("mapRef"));
  let params;
  echarts.registerMap('china', chinaGeoJson); // 注册地图
  params = chinaGeoJson.features.map(item => {
    if (areaColor[item.properties.adcode]) {
      regionsList.value.push(
        {
          name: item.properties.name,
          itemStyle: {
            areaColor: areaColor[item.properties.adcode],
            // borderColor: '#880000',
          },
          label: {
            show: true, // 单独设置显示
            color: '#fff',
            fontSize: 12,
            fontWeight: 200,
            fontFamily: 'Microsoft YaHei', // 字体
          },
          emphasis: { //鼠标悬停样式
            itemStyle: {
              areaColor: 'rgba(39, 59, 130)',
            },
            label: {
              // show: true,
              // fontSize: 12,
              // fontWeight: 'bold'
              show: true,
              fontSize: 12,
              fontWeight: 'bold',
              color: '#fff', // 明确设置悬停文本颜色为白色
              // 可以添加其他效果
              textBorderColor: '#000',
              textBorderWidth: 1,
              textShadowBlur: 4
            }
          },
        }
      )
    }
    return {
      name: item.properties.name,
      adcode: item.properties.adcode,
      parent: item.properties.parent,
      level: item.properties.level,
      _level_: item.properties.level,
    }
  })
  initEcharts("china", params);
}


// 根据 adcode 获取原始地图json数据
function getJSON({ name, adcode }: any, callback: any) {

  const url = `https://geo.datav.aliyun.com/areas_v3/bound/${adcode}_full.json`;
  fetch(url)
    .then(res => {
      if (!res.ok || res.status !== 200) return
      // status不等于200 ok为false 时不往下走
      return res.json()
    })
    .then(data => {
      if (data) {
        callback(data);
      }
    })
    .catch(error => {
    });
}
// 渲染地图
function renderChart(name: any, data: any) {
  // 注册地图
  echarts.registerMap(name, data);
  // 根据 json 数据拼装 mapdata， 用于地图点击下钻时传递数据，主要有adcode、name
  const mapdata = data.features.map((item) => {
    return item.properties;
  });
  // 配置option
  initEcharts(name, mapdata);
}

// 省份与省会对照表
const provinceCapitalMap = {
  '北京': '北京',
  '上海': '上海',
  '天津': '天津',
  '重庆': '重庆',
  '河北': '石家庄',
  '山西': '太原',
  '辽宁': '沈阳',
  '吉林': '长春',
  '黑龙江': '哈尔滨',
  '江苏': '南京',
  '浙江': '杭州',
  // 其他省份...
};
// 省ponit 列表
const getProvince = async (adcode: any) => {
  pointList.value = []
  lineList.value = []
  try {
    const res: any = await post(mapApi.province, { code: adcode })
    if (res.code === '0000') {
      const pointList = res.data.map((item: any) => ({
        name: item.name,
        value: [item.lngX, item.latY, item.num],
        code: item.code,
        haveOrg: item.haveOrg,
        symbol: `image://${ponitImg}`,
        symbolSize: [20, 20]
      }));
      return pointList

    }
  } catch (error) {
    console.log(error, 'getProvince')
  }
}
// 市point 列表
const getCity = async (adcode: any) => {
  pointList.value = []
  lineList.value = []
  try {
    const res: any = await post(mapApi.city, { code: adcode })
    if (res.code === '0000') {
      const cityList = res.data.map((item: any) => ({
        name: item.name,
        value: [item.lngX, item.latY, item.num],
        code: item.code,
        haveOrg: item.haveOrg,
        symbol: `image://${ponitImg}`,
        symbolSize: [20, 20]
      }));
      return cityList
    }
  } catch (error) {
    console.log(error, 'getCity')
  }
}
// 获取分拨中心point
const getGetFbzxInfo = async (adcode: any) => {
  try {
    const res: any = await post(mapApi.getFbzxInfo, { code: adcode })
    if (res.code === '0000') {
      const fbzxList = {
        name: res.data.name,
        value: [res.data.lngX, res.data.latY, res.data.num],
        code: res.data.code,
        haveOrg: res.data.haveOrg,
        isFbzx: true,
        symbol: `image://${cityPointImg}`,
        symbolSize: [38, 38],
        label: {
          show: true,
          formatter: '{b}', // 显示点位名称
          position: 'top', // 标签位置
          color: '#E98D1A', // 文字颜色
          fontSize: 12,
          fontWeight: 400,
          backgroundColor: '#020307', // 背景颜色
          borderColor: '#E98D1A', // 边框颜色
          borderWidth: 2, // 边框宽度
          borderType: 'solid', // 边框类型
          // borderRadius: 4, // 边框圆角
          padding: [4, 10], // 内边距

        },
      }
      return fbzxList
    }

  } catch (error) {
    console.log(error, 'getGetFbzxInfo')
  }
}



// 全国信息
const getNational = async () => {
  pointList.value = []
  lineList.value = []
  try {
    const res: any = await post(mapApi.national)
    if (res.code === '0000') {
      const nationalList = res.data.map((item: any) => ({
        name: item.name,
        value: [item.lngX, item.latY],
        code: item.code,
        haveOrg: item.haveOrg
      }));
      return nationalList
    }
  } catch (error) {
    console.log(error, 'getNational')
  }
}

// 返回上一级地图
const goBack = async () => {
  if (drillDownHistory.value.length >= 2) {
    const { name, adcode } = drillDownHistory.value[drillDownHistory.value.length - 2];
    drillDownHistory.value.splice(-2, 2);

    // 获取城市级别分拨中心点位
    const fbzxData: any = await getGetFbzxInfo(adcode);
    if (fbzxData && Object.keys(fbzxData).length) {
      // 为分拨中心点位添加标识
      fbzxPointList.value = [fbzxData];

      // 调用 省point 列表
      const provinceData = await getProvince(adcode)
      pointList.value = [...provinceData, ...fbzxPointList.value];
      getJSON({ name, adcode }, function (data: any) {
        renderChart(name, data);
      });
    }
  } else {
    seriesPoingState.value = false
    // 如果只有一个历史记录，直接返回到全国地图
    drillDownHistory.value = [];
    pointList.value = await getNational()
    getLineList()
    initMap()
  }
}

const handleMapClick = (params: any) => {
  // 清除之前的定时器
  if (clickTimeout) {
    clearTimeout(clickTimeout);
    clickTimeout = null;
  }
  // 设置新的防抖定时器
  clickTimeout = setTimeout(async () => {
    if (!params.data || params.seriesType === 'lines') {
      // 空白处不处理，交由容器click事件处理
      return;
    }
    // 点击有数据的区域，继续下钻
    const { adcode, name, level } = params.data;
    if (!adcode) return

    //   

    // 判断如果是 district 层级，则提示用户已经为最底级了
    if (level === "city" || level === "province") {
      // 获取城市级别分拨中心点位
      const fbzxData: any = await getGetFbzxInfo(adcode);
      if (fbzxData && Object.keys(fbzxData).length) {
        // 为分拨中心点位添加标识
        fbzxPointList.value = [fbzxData];
      }
      if (level === "province" && !areaColor[adcode]) return

      // 获取下钻数据
      const data = level === "province"
        ? await getProvince(adcode)
        : await getCity(adcode);

      pointList.value = [...data, ...fbzxPointList.value];
    }
    // 控制ponit旗帜显示
    if (pointList.value.length) {
      seriesPoingState.value = true
    }
    // 点击地图下钻时记录name和adcode
    drillDownHistory.value.push({ name, adcode });
    getJSON({ name, adcode }, function (data: any) {
      renderChart(name, data);
    });

    clickTimeout = null;
  }, 300); // 调整为300ms防抖
}
const handleCanvasClick = (params: any) => {
  // 点击地图空白处返回上一级
  if (!params.target && seriesPoingState.value) {
    goBack()
  }
}

const getList = async () => {
  try {
    const res: any = await post(statistics.orderSummary)
    if (res.code === '0000' && res.data) {
      const { orderNum, num, feeWeight } = res.data
      const newData = [
        {
          img: votesImg,
          text1: '当日总票数',
          text2: orderNum,
          unit: '票',
          width: '194px'
        },
        {
          img: piecesIimg,
          text1: '当日总件数',
          text2: num,
          unit: '件',
          width: '187px'
        },
        {
          img: throughputImg,
          text1: '当日总吞吐量',
          text2: feeWeight,
          unit: '票',
          width: '207px'
        }
      ]
      titleData.splice(0, titleData.length, ...newData);
    }
  } catch (error) {
    console.log(error, 'getList')
  }
}

onMounted(async () => {
  await getList()
  pointList.value = await getNational()
  getLineList()
  await initMap()
  myChart.value.on('click', handleMapClick);
  myChart.value.getZr().on("click", handleCanvasClick)
});

onUnmounted(() => {
  myChart.value.off('click', handleMapClick);
  myChart.value.getZr().off('click', handleCanvasClick);
});

</script>

<template>
  <div class="centermap">
    <div class="maptitle">
      <div class="zuo flex h-full" v-for="(item, index) in titleData" :key="index"
        :style="[{ width: item.width }, { 'margin-right': index === titleData.length - 1 ? '0' : '60px' }]">
        <img :src="item.img" class="w-[72px] h-[72px] mr-[15px]" alt="">
        <div class="zuo-text flex flex-col justify-between w-full">
          <span class="text1 h-[28px] flex items-center ">{{ item.text1 }}</span>
          <span class="text2 h-[45px] flex items-center ">{{ item.text2 }} <span
              class="unit pl-[8px] h-full flex items-end ">{{ item.unit }}</span></span>
        </div>
      </div>
    </div>
    <div class="mapwrap w-full flex-1">
      <div class="w-full h-full map-container" id="mapRef"></div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.centermap {
  flex: 1;
  margin-bottom: 10px;
  display: flex;
  flex-direction: column;

  .maptitle {
    margin: 2px 68px 0 46px;
    height: 75px;
    display: flex;
    box-sizing: border-box;
  }

  .mapwrap {
    perspective: 1000px;
    background: transparent;
    overflow: hidden;
    position: relative;

    .map-container {
      width: 100%;
      height: 100%;
      position: relative;
      z-index: 2; // 确保地图在背景之上
      
    }

    //
  }

  // 使用伪元素实现3D旋转背景
  .map-container::before {
    content: '';
    position: absolute;
    bottom: 0;
    left: 15%;
    width: 600px;
    height: 400px;
    background: url('@/assets/img/content-img/map-bg-img.png') no-repeat center center;
    background-size: 100% 100%;
    transform-style: preserve-3d;
    // animation: rotate3d 1s infinite linear;
     animation: rotate3d 20s linear infinite;
    z-index: 0; // 背景在地图之下
  }
}

// 3D旋转动画
@keyframes rotate3d {
  0% {
    transform: rotateY(0deg);
  }

  25% {
    transform: rotateY(15deg);
  }

  50% {
    transform: rotateY(30deg);
  }

  75% {
    transform: rotateY(15deg);
  }

  100% {
    transform: rotateY(0deg);
  }
}

.text1 {
  font-family: Alibaba PuHuiTi 3.0, Alibaba PuHuiTi 30;
  font-weight: 400;
  font-size: 20px;
  color: rgba(255, 255, 255, 0.64);
  line-height: 28px;
  text-align: left;
  font-style: normal;
  text-transform: none;
}

.text2 {
  font-family: HarmonyOS Sans SC, HarmonyOS Sans SC;
  font-weight: 700;
  font-size: 32px;
  color: rgba(255, 255, 255, 0.87);
  line-height: 45px;
  text-align: left;
}

.unit {
  font-family: Alibaba PuHuiTi 3.0, Alibaba PuHuiTi 30;
  font-weight: 400;
  font-size: 20px;
  color: rgba(255, 255, 255, 0.64);
  line-height: 28px;
  text-align: left;
}
</style>
